﻿using System;
using System.IO;
using Ingr.SP3D.Common.Middle;
using Ingr.SP3D.Common.Middle.Services;
using Ingr.SP3D.CommonSymbolFunctions;
using Ingr.SP3D.Content;
using Ingr.SP3D.Equipment.Middle;
using Ingr.SP3D.ReferenceData.Middle;

namespace Ingr.SP3D.SEIDDP
{
    //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    //   ProgID: SEIDDP,Ingr.SP3D.SEIDDP.IKG1
    //   Author:  Yuanpeng Zhang 
    //   Description: IKG1,反编译过来

    //   Change History:
    //   version        data              who                change description
    //   =======        ===========       ==============     ==========================================================================================
    //   2.0.0.0        2025-10-15        Yuanpeng Zhang     .net反编译
    //   2.0.0.1        2025-10-16        Yuanpeng Zhang     增强校验，对Actuator height-Actuator height 1=Valve height情况抛出更准确的异常提示
    //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    [CacheOption(CacheOptionType.NonCached)]
    [VariableOutputs]
    [SymbolVersion("2.0.0.1")]
    public class IKG1 : CustomSymbolDefinition //继承后者的类
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        public IKG1() : base()
        {
            //有多少个port，就会重复进来多少次
            //这个dll就类似于pid的datasource对象           
            string DllPath = MiddleServiceProvider.SiteMgr.ActiveSite.ActivePlant.PlantCatalog.SymbolShare + @"\Custom Symbols\CommonSymbolFunctions.dll";
            if (File.Exists(DllPath) == false)
            {
                throw new Exception(@"SharedContent\Custom Symbols\CommonSymbolFunctions.dll 未找到，symbol无法工作");
            }
            else
            {
                Ingr.SP3D.Content.CommonSymbolFunctionLoader.Load();
            }
        }

        #region "用于接收Definition of Inputs的代码体内的变量"
        /// <summary>
        /// 来自ddp
        /// </summary>
        public double parFace1toCenter, parFace2toCenter, parValveHeight, parValveHeight1, parValveWidth, parActuatorHeight, parActuatorHeight1, parActuatorDiameter, parInsulationThickness, parOperationHeight, parOperationDiameter;
        public double parPortIndex2, parPortIndex1, parNpd2, parNpd1, parNpd;
        public double parEndPreparation, parScheduleThickness, parEndStandard, parPressureRating, parFlowDirection,
            parEndPreparation1, parScheduleThickness1, parEndStandard1, parPressureRating1, parFlowDirection1,
            parEndPreparation2, parScheduleThickness2, parEndStandard2, parPressureRating2, parFlowDirection2;
        public string parNpdUnitType, parNpdUnitType1, parId1, parNpdUnitType2, parId2;
        #endregion

        #region "Definition of Inputs,会从3D后台中带过来参数" 
        //这个1 2 3 4代表了唯一的序号，先后顺序。因为所有的输入参数被视为一个集合
        //名字要和bulkload表里的属性名字一致。顺序、描述其实无所谓,外部的参数会根据Name自动匹配到对应的某一个参数中。
        [InputCatalogPart(1)]
        public InputCatalogPart partFclt;
        [InputDouble(2, "Face1toCenter", "Face1 to Center", 0.1,true)]
        public InputDouble m_Face1toCenter;
        [InputDouble(3, "Face2toCenter", "Face2 to Center", 0.1,true)]
        public InputDouble m_Face2toCenter;
        [InputDouble(4, "ValveHeight", "Valve Height", 0.4,true)]
        public InputDouble m_ValveHeight;
        [InputDouble(5, "ValveHeight1", "Valve Height1", 0.35, true)]
        public InputDouble m_ValveHeight1;
        [InputDouble(6, "ValveWidth", "Valve Width", 0.4, true)]
        public InputDouble m_ValveWidth;
        [InputDouble(7, "ActuatorHeight", "Actuator Height", 0.9, true)]
        public InputDouble m_ActuatorHeight;
        [InputDouble(8, "ActuatorHeight1", "Actuator Height1", 0.4, true)]
        public InputDouble m_ActuatorHeight1;
        [InputDouble(9, "ActuatorDiameter", "Actuator Diameter", 0.25, true)]
        public InputDouble m_ActuatorDiameter;
        [InputDouble(10, "OperationHeight", "Operation Height", 0.5)]
        public InputDouble m_OperationHeight;
        [InputDouble(11, "OperationDiameter", "Operation Diameter", 0.5)]
        public InputDouble m_OperationDiameter;
        [InputDouble(12, "InsulationThickness", "Insulation Thickness", 0.025, true)]
        public InputDouble m_InsulationThickness;

        [InputDouble(13, "Npd", "NPD", 100.0, true)]
        public InputDouble m_Npd;
        [InputDouble(14, "EndPreparation", "End Preparation", 21, true)]
        public InputDouble m_EndPreparation;
        [InputDouble(15, "ScheduleThickness", "Schedule Thickness", 100, true)]
        public InputDouble m_ScheduleThickness;
        [InputDouble(16, "EndStandard", "End Standard", 5, true)]
        public InputDouble m_EndStandard;
        [InputDouble(17, "PressureRating", "Pressure Rating", 35, true)]
        public InputDouble m_PressureRating;
        [InputDouble(18, "FlowDirection", "Flow Direction", 3, true)]
        public InputDouble m_FlowDirection;

        //port的话  9个一组
        [InputDouble(19, "PortIndex1", "Port Index 1", 1, true)]
        public InputDouble m_PortIndex1;
        [InputDouble(20, "Npd1", "Npd 1", 0, true)]
        public InputDouble m_Npd1;
        [InputDouble(21, "EndPreparation1", "End Preparation 1", 0, true)]
        public InputDouble m_EndPreparation1;
        [InputDouble(22, "ScheduleThickness1", "Schedule Thickness 1", 0, true)]
        public InputDouble m_ScheduleThickness1;
        [InputDouble(23, "EndStandard1", "End Standard 1", 0, true)]
        public InputDouble m_EndStandard1;
        [InputDouble(24, "PressureRating1", "Pressure Rating 1", 0, true)]
        public InputDouble m_PressureRating1;
        [InputDouble(25, "FlowDirection1", "Flow Direction 1", 0, true)]
        public InputDouble m_FlowDirection1;

        [InputDouble(26, "PortIndex2", "Port Index 2", 2, true)]
        public InputDouble m_PortIndex2;
        [InputDouble(27, "Npd2", "Npd 2", 0, true)]
        public InputDouble m_Npd2;
        [InputDouble(28, "EndPreparation2", "End Preparation 2", 0, true)]
        public InputDouble m_EndPreparation2;
        [InputDouble(29, "ScheduleThickness2", "Schedule Thickness 2", 0, true)]
        public InputDouble m_ScheduleThickness2;
        [InputDouble(30, "EndStandard2", "End Standard 2", 0, true)]
        public InputDouble m_EndStandard2;
        [InputDouble(31, "PressureRating2", "Pressure Rating 2", 0, true)]
        public InputDouble m_PressureRating2;
        [InputDouble(32, "FlowDirection2", "Flow Direction 2", 0, true)]
        public InputDouble m_FlowDirection2;

        [InputString(33, "Id1", "Id1", "1")]
        public InputString m_Id1;
        [InputString(34, "Id2", "Id2", "2")]
        public InputString m_Id2;
        [InputString(35, "NpdUnitType", "Npd Unit Type", "mm")]
        public InputString m_NpdUnitType;
        [InputString(36, "NpdUnitType1", "Npd Unit Type 1", "")]
        public InputString m_NpdUnitType1;
        [InputString(37, "NpdUnitType2", "Npd Unit Type 2", "")]
        public InputString m_NpdUnitType2;
        #endregion

        #region "Definitions of Aspects and their Outputs"
        //名字要在实际outputs.add时，匹配上
        [Aspect("Physical", "Physical", AspectID.SimplePhysical)]
        [SymbolOutput("PNoz1", "Nozzle 1")]
        [SymbolOutput("PNoz2", "Nozzle 2")]
        [SymbolOutput("ActuatorBody", "Actuator Body")]
        [SymbolOutput("Stem", "Stem between Valve and Actuator Body")]
        [SymbolOutput("ValveBody", "Cylindrical Body of Valve")]
        [SymbolOutput("ValveBoxBody", "Box Body of Valve")]
        public AspectDefinition m_Physical;

        // Token: 0x0400004B RID: 75
        [SymbolOutput("ValveBodyIns", "Valve Body Insulation")]
        [Aspect("Insulation", "Insulation", AspectID.Insulation)]
        public AspectDefinition m_Insulation;

        // Token: 0x0400004C RID: 76
        [SymbolOutput("OpEnvelope", "Envelop for Operation ")]
        [Aspect("Operation", "Operation", AspectID.Operation)]
        public AspectDefinition m_Operation;
        #endregion

        #region "Construct Outputs"
        protected override void ConstructOutputs()
        {
            try
            {
                parFace1toCenter = m_Face1toCenter.Value;
                parFace2toCenter = m_Face2toCenter.Value;
                parValveHeight = m_ValveHeight.Value;
                parValveHeight1 = m_ValveHeight1.Value;
                parValveWidth = m_ValveWidth.Value;
                parActuatorHeight = m_ActuatorHeight.Value;
                parActuatorHeight1 = m_ActuatorHeight1.Value;
                parActuatorDiameter = m_ActuatorDiameter.Value;
                parInsulationThickness = m_InsulationThickness.Value;
                parNpd = m_Npd.Value;
                parEndPreparation = m_EndPreparation.Value;
                parScheduleThickness = m_ScheduleThickness.Value;
                parEndStandard = m_EndStandard.Value;
                parPressureRating = m_PressureRating.Value;
                parFlowDirection = m_FlowDirection.Value;
                parPortIndex1 = m_PortIndex1.Value;
                parNpd1 = m_Npd1.Value;
                parEndPreparation1 = m_EndPreparation1.Value;
                parScheduleThickness1 = m_ScheduleThickness1.Value;
                parEndStandard1 = m_EndStandard1.Value;
                parPressureRating1 = m_PressureRating1.Value;
                parFlowDirection1 = m_FlowDirection1.Value;
                if (parFlowDirection1 == 0.0)
                {
                    parFlowDirection1 = parFlowDirection;
                }
                if (parNpd1 == 0.0)
                {
                    parNpd1 = parNpd;
                }
                if (parEndPreparation1 == 0.0)
                {
                    parEndPreparation1 = parEndPreparation;
                }
                if (parScheduleThickness1 == 0.0)
                {
                    parScheduleThickness1 = parScheduleThickness;
                }
                if (parEndStandard1 == 0.0)
                {
                    parEndStandard1 = parEndStandard;
                }
                if (parPressureRating1 == 0.0)
                {
                    parPressureRating1 = parPressureRating;
                }
                parPortIndex2 = m_PortIndex2.Value;
                parNpd2 = m_Npd2.Value;
                parEndPreparation2 = m_EndPreparation2.Value;
                parScheduleThickness2 = m_ScheduleThickness2.Value;
                parEndStandard2 = m_EndStandard2.Value;
                parPressureRating2 = m_PressureRating2.Value;
                parFlowDirection2 = m_FlowDirection2.Value;
                if (parFlowDirection2 == 0.0)
                {
                    parFlowDirection2 = parFlowDirection;
                }
                if (parNpd2 == 0.0)
                {
                    parNpd2 = parNpd;
                }
                if (parEndPreparation2 == 0.0)
                {
                    parEndPreparation2 = parEndPreparation;
                }
                if (parScheduleThickness2 == 0.0)
                {
                    parScheduleThickness2 = parScheduleThickness;
                }
                if (parEndStandard2 == 0.0)
                {
                    parEndStandard2 = parEndStandard;
                }
                if (parPressureRating2 == 0.0)
                {
                    parPressureRating2 = parPressureRating;
                }
                parOperationHeight = m_OperationHeight.Value;
                parOperationDiameter = m_OperationDiameter.Value;
                parId1 = m_Id1.Value;
                parId2 = m_Id2.Value;
                parNpdUnitType = m_NpdUnitType.Value;
                parNpdUnitType1 = m_NpdUnitType1.Value;
                parNpdUnitType2 = m_NpdUnitType2.Value;
                PipeComponent pipeComponent = (PipeComponent)partFclt.Value;
                SP3DConnection occurrenceConnection = OccurrenceConnection;
                int partDataBasis = pipeComponent.PartDataBasis;
                Run(pipeComponent, occurrenceConnection);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        private void Run(PipeComponent pipeComponent, SP3DConnection connection)
        {
            try
            {
                UtilityFunctions.CheckParameterForZeroValues(this, new string[]
                {
                    "ValveHeight1",
                    "ValveWidth",
                    "ActuatorHeight1",
                    "ActuatorDiameter",
                    "OperationHeight",
                    "OperationDiameter"
                });
                double[] array = new double[2];
                double[] array2 = new double[2];
                double[] array3 = new double[2];
                double[] array4 = new double[2];
                double[] array5 = new double[2];
                PipeNozzle pipeNozzle = PortHelper.CreateDynamicPipePort(connection, 1, parNpd1, parNpdUnitType1, (int)parEndPreparation1, (int)parScheduleThickness1, (int)parEndStandard1, (int)parPressureRating1, (int)parFlowDirection1, parId1, 5, false, new Position(-parFace1toCenter, 0.0, 0.0), new Vector(-1.0, 0.0, 0.0), true, true);
                PipeNozzle pipeNozzle2 = PortHelper.CreateDynamicPipePort(connection, 2, parNpd2, parNpdUnitType2, (int)parEndPreparation2, (int)parScheduleThickness2, (int)parEndStandard2, (int)parPressureRating2, (int)parFlowDirection2, parId2, 5, false, new Position(parFace2toCenter, 0.0, 0.0), new Vector(1.0, 0.0, 0.0), true, true);
                UtilityFunctions.GetPipingPortData(pipeComponent, pipeNozzle, out array[0], out array5[0], out array3[0], out array2[0], out array4[0], true);
                UtilityFunctions.GetPipingPortData(pipeComponent, pipeNozzle2, out array[1], out array5[1], out array3[1], out array2[1], out array4[1], true);
                double diameter = 0.05;
                Position position = new Position(-parFace1toCenter, 0.0, 0.0);
                Position position2 = new Position(parFace2toCenter, 0.0, 0.0);
                Projection3d output = Graphics3D.CreateCylinder(position, position2, array[0], true);
                m_Physical.Outputs.Add("ValveBody", output);
                position.Set(-parFace1toCenter, 0.0, parValveWidth / 2.0);
                position2.Set(parFace2toCenter, parValveHeight1, -parValveWidth / 2.0);
                Projection3d output2 = Graphics3D.CreateBox(position, position2);
                m_Physical.Outputs.Add("ValveBoxBody", output2);
                position.Set(0.0, parActuatorHeight - parActuatorHeight1, 0.0);
                position2.Set(0.0, parActuatorHeight, 0.0);
                Projection3d output3 = Graphics3D.CreateCylinder(position, position2, parActuatorDiameter, true);
                m_Physical.Outputs.Add("ActuatorBody", output3);
                position.Set(0.0, parActuatorHeight - parActuatorHeight1, 0.0);
                position2.Set(0.0, parValveHeight1, 0.0);
                if (parActuatorHeight - parActuatorHeight1 - parValveHeight1< Math3d.DistanceTolerance)
                {
                    throw new Exception(@"参数设定错误： ActuatorHeight - ActuatorHeight1不允许等于ValveHeight1");
                }
                Projection3d output4 = Graphics3D.CreateCylinder(position, position2, diameter, true);
                m_Physical.Outputs.Add("Stem", output4);
                m_Physical.Outputs.Add("PNoz1", pipeNozzle);
                m_Physical.Outputs.Add("PNoz2", pipeNozzle2);
                UtilityFunctions.GetPipingPortData(pipeComponent, pipeNozzle, out array[0], out array5[0], out array3[0], out array2[0], out array4[0], true);
                UtilityFunctions.GetPipingPortData(pipeComponent, pipeNozzle2, out array[1], out array5[1], out array3[1], out array2[1], out array4[1], true);
                double num = ReturnMax4(array[0], array[1], array3[0], array3[1]);
                position.Set(-parFace1toCenter - parInsulationThickness, -num / 2.0 - parInsulationThickness, parValveWidth / 2.0 + parInsulationThickness);
                position2.Set(parFace2toCenter + parInsulationThickness, parValveHeight1 + parInsulationThickness, -parValveWidth / 2.0 - parInsulationThickness);
                Projection3d output5 = Graphics3D.CreateBox(position, position2);
                m_Insulation.Outputs.Add("ValveBodyIns", output5);
                position.Set(0.0, parActuatorHeight, 0.0);
                position2.Set(0.0, parActuatorHeight + parOperationHeight, 0.0);
                Projection3d output6 = Graphics3D.CreateCylinder(position, position2, parOperationDiameter, true);
                m_Operation.Outputs.Add("OpEnvelope", output6);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        private double ReturnMax4(double A, double B, double C, double D)
        {
            double result;
            try
            {
                double num = A;
                if (num < B)
                {
                    num = B;
                }
                if (num < C)
                {
                    num = C;
                }
                if (num < D)
                {
                    num = D;
                }
                result = num;
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return result;
        }

        #endregion

    }
}
